from odoo import fields, models, api, _
from odoo.exceptions import UserError, ValidationError


class ProductCodingTemplate(models.Model):
    _name = 'product.coding.template'
    _description = 'Product Coding Template'
    _inherit = ['mail.thread', 'mail.activity.mixin']

    # 物料描述-中
    name = fields.Char('Name【Chinese】')
    # 物料描述-英
    name_en = fields.Char('Name【English】')
    # 型号
    specification = fields.Char('specification', readonly=True)
    previous_categ_id = fields.Many2one('product.category')
    category_id = fields.Many2one('product.category', 'Category',
                                  domain=['|', ("f_code", "in", ['MC']), ("code", "in", ['CR', 'BS'])])
    f_category_id = fields.Many2one('product.category', compute="compute_f_category_id", store=True)
    s_f_code = fields.Char('Code', related='f_category_id.code')
    default_code = fields.Char('Default code', compute='_compute_coding_attribute', copy=False, store=True,
                               readonly=False)
    # versions = fields.Char('versions', default='A0')
    product_tmpl_id = fields.Many2one('product.template', 'Product Template', copy=False)
    # 记录历史生成的产品
    product_tmpl_ids = fields.One2many('product.template', 'product_coding_id', string="History Product Template",
                                       copy=False)
    product_coding_attribute_ids = fields.One2many('product.template.coding.attribute',
                                                   'product_coding_id',
                                                   string="Coding Attribute Selection List", copy=True)
    uom_id = fields.Many2one('uom.uom', 'Unit of Measure', required=True, domain="[('id', 'in', t_uom_ids)]")
    uom_po_id = fields.Many2one('uom.uom', 'Unit of Measure PO', domain="[('id', 'in', t_po_uom_ids)]")
    # 是否指定供应商/部门
    is_coding_provider = fields.Boolean(default=True)
    is_coding_department = fields.Boolean(default=True)
    is_model_number = fields.Boolean(default=False)

    coding_provider_id = fields.Many2one('res.partner', string="Supplier", domain="[('supplier_rank', '>', 0),('code', '!=', False)]")
    coding_specification = fields.Html(string="Coding specification", related="category_id.coding_specification")
    supplier_choice = fields.Selection([('yes', 'Yes'), ('not', 'Not')], string="Designated supplier")
    department_choice = fields.Selection([('multi', 'Multiple departments'), ('single', 'Individual department')],
                                         string="Using Department")
    department_id = fields.Many2one('hr.department', string="Department", domain=[('parent_id', '!=', False)])
    # 提示
    coding_note = fields.Text(string="Coding Note", related="category_id.coding_note")
    # 页面搜索框
    search_arg = fields.Char(string='Search Arg')
    # 页面搜索字段展示
    template_ids = fields.Many2many('product.coding.template', 'template_search_rel', 'temp1_id', 'temp2_id',
                                    'Search Record')
    # 芯板型号选择
    model_library_id = fields.Many2one('sb.model.library', string="型号",
                                       domain="[('id', 'in', t_model_library_ids)]")
    approval_text = fields.Text('Approval Text', compute='_compute_approve', store=True)

    # 可选单位范围ids字段
    t_uom_ids = fields.Many2many('uom.uom', compute='_compute_t_uom_ids')
    t_po_uom_ids = fields.Many2many('uom.uom', compute='_compute_t_uom_ids')
    # 可选型号范围ids字段
    t_model_library_ids = fields.Many2many('sb.model.library', compute='_compute_t_model_library_ids')

    # 产品form跳转
    def action_product(self):
        if self.product_tmpl_id.id:
            return {
                "name": _("Product"),
                "type": "ir.actions.act_window",
                "view_mode": "form",
                "res_model": "product.template",
                "res_id": self.product_tmpl_id.id,
                "target": "new",
            }
        else:
            return False

    @api.depends('category_id')
    def _compute_t_uom_ids(self):
        uom_ids = self.env['uom.uom'].sudo().search([])
        for item in self:
            if item.category_id and item.category_id.parent_id.code in ['CR'] or item.category_id.code in ['CR']:
                self.t_uom_ids = self.env['uom.uom'].sudo().search([('code', '=', 'zhang')])
                self.t_po_uom_ids = self.env['uom.uom'].sudo().search([('code', '=', 'zhang')])
            elif item.category_id and item.category_id.parent_id.code in ['BS'] or item.category_id.code in ['BS']:
                self.t_uom_ids = self.env['uom.uom'].sudo().search(['|', ('code', '=', 'M2'), ('code', '=', 'zhang')])
                self.t_po_uom_ids = self.env['uom.uom'].sudo().search(['|', '|', ('code', '=', 'M2'),
                                                                       ('code', '=', 'zhang'), ('name', 'ilike', 'pp卷')])
            else:
                self.t_uom_ids = uom_ids
                self.t_po_uom_ids = uom_ids

    @api.depends('coding_provider_id')
    def _compute_t_model_library_ids(self):
        model_library_ids = self.env['sb.model.library'].sudo().search([])
        for item in self:
            if item.coding_provider_id:
                self.t_model_library_ids = self.env['sb.model.library'].sudo().search([('coding_provider_id', '=', item.coding_provider_id.id)])
            else:
                self.t_model_library_ids = model_library_ids

    @api.depends('sb_workflow_item_ids', 'sb_workflow_item_ids.approval_instructions')
    def _compute_approve(self):
        for record in self:
            if record.sb_workflow_item_ids:
                text = ''
                for txt in record.sb_workflow_item_ids:
                    if not txt.approval_instructions:
                        continue
                    text += f"""{txt.approval_instructions}
                            """
                record.approval_text = text
            else:
                record.approval_text = False

    @api.depends('category_id')
    def compute_f_category_id(self):
        for res in self:
            res.f_category_id = res.category_id.parent_id if res.category_id.parent_id else res.category_id

    @api.onchange('f_category_id')
    def _onchange_f_category_id(self):
        for record in self:
            # 如果为耗材, 需要置空所有编码属性选择列表
            if record.s_f_code == 'MC':
                self.product_coding_attribute_ids.update({'material_coding_attribute_value_id': False})

    @api.onchange('search_arg')
    def _onchange_template_ids(self):
        for rec in self:
            if rec.search_arg:
                rec.template_ids = None
                rec.template_ids = self.search(['|', ('name', 'ilike', rec.search_arg),
                                                ('name_en', 'ilike', rec.search_arg)]).ids

    # 当产品类别改变，重置编码属性选择列表
    @api.onchange('category_id')
    def onchange_categ_id(self):
        if self.state == 'draft' or self.state == 'rejected':
            # if not self.previous_categ_id or self.previous_categ_id.id != self.category_id.id:
            if self.category_id:
                self.product_coding_attribute_ids = False
                # 芯板
                if self.category_id.parent_id.code in ['CR', 'BS'] or self.category_id.code in ['CR', 'BS']:
                    self.is_coding_provider = True
                    self.is_coding_department = False
                    self.is_model_number = True
                    self.supplier_choice = 'yes'
                else:
                    self.is_coding_provider = True
                    self.is_coding_department = True
                    self.is_model_number = False
            product_category_coding_list_ids = self.category_id.product_category_coding_list_ids
            if product_category_coding_list_ids:
                it = []
                for item in product_category_coding_list_ids:
                    it.append({
                        'sb_material_coding_attribute_id': item.sb_material_coding_attribute_id.id,
                        'coding_description': item.coding_description,
                        'coding_participation': item.coding_participation,
                        # 'placeholder': item.sb_material_coding_attribute_id.input_placeholder,
                        'sequence': item.sequence,
                    })
                sort_it = sorted(it, key=lambda x: x['sequence'], reverse=False)
                self.write({'product_coding_attribute_ids': [(0, 0, x) for x in sort_it]})

    @api.onchange('supplier_choice')
    def onchange_supplier_choice(self):
        if self.supplier_choice == 'not':
            # self.product_coding_attribute_ids.filtered(lambda x: x.coding_attribute_type == 'partner').update({
            #     'coding_provider_id': False
            # })
            self.coding_provider_id = False

    @api.onchange('department_choice')
    def onchange_department_choice(self):
        if self.department_choice == 'multi':
            #     self.product_coding_attribute_ids.filtered(lambda x: x.coding_attribute_type == 'department').update({
            #         'department_id': False
            #     })
            # else:
            self.department_id = False

    def get_category_name(self, category_id, name=''):
        if name:
            n = (category_id.name or '') + '_' + name
        else:
            n = category_id.name or ''
        if category_id.parent_id:
            return self.get_category_name(category_id.parent_id, n)
        return n

    def get_category_name_en(self, category_id, name=''):
        if name:
            n = (category_id.en_name or '') + '_' + name
        else:
            n = category_id.en_name
        if category_id.parent_id:
            return self.get_category_name_en(category_id.parent_id, n)
        return n

    def write(self, vals):
        if vals.get('category_id'):
            vals['previous_categ_id'] = vals.get('category_id')
        if vals.get('template_ids'):
            vals['template_ids'] = [(5, 0, 0)]
        if vals.get('search_arg'):
            vals['search_arg'] = ''
        res = super(ProductCodingTemplate, self).write(vals)
        return res

    @api.onchange('model_library_id')
    def onchange_model_library_id(self):
        l_id = self.env['sb.model.library'].search([('id', '=', self.model_library_id.id)], limit=1)
        if l_id.category_id and self.category_id.code == 'CR':
            self.write({
                'category_id': l_id.category_id.id
            })
        elif l_id.pp_category_id and self.category_id.code == 'BS':
            self.write({
                'category_id': l_id.pp_category_id.id
            })
        if l_id.coding_provider_id:
            self.write({
                'coding_provider_id': l_id.coding_provider_id.id
            })
        # if self.product_coding_attribute_ids:
        #     for item in self.product_coding_attribute_ids:
        #         if item.sb_material_coding_attribute_id.code == 'LS':
        #             vid = item.env['sb.material.coding.attribute.value'].search(
        #                 [('material_coding_attribute_id', '=', item.sb_material_coding_attribute_id.id),
        #                  ('value_code', '=', self.model_library_id.halogen)], limit=1)
        #             if vid:
        #                 item.write({
        #                     'material_coding_attribute_value_id': vid.id
        #                 })
        #         if item.sb_material_coding_attribute_id.code == 'XS':
        #             xvid = item.env['sb.material.coding.attribute.value'].search(
        #                 [('material_coding_attribute_id', '=', item.sb_material_coding_attribute_id.id),
        #                  ('value_code', '=', self.model_library_id.core_color)], limit=1)
        #             if xvid:
        #                 item.write({
        #                     'material_coding_attribute_value_id': xvid.id
        #                 })

    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            if vals.get('category_id'):
                vals['previous_categ_id'] = vals.get('category_id')
            if vals.get('template_ids'):
                vals['template_ids'] = [(5, 0, 0)]
            if vals.get('search_arg'):
                vals['search_arg'] = ''
        return super(ProductCodingTemplate, self).create(vals_list)

    # 供应商编码获取

    @api.depends('product_coding_attribute_ids', 'coding_provider_id', 'department_id', 'model_library_id',
                 'product_coding_attribute_ids.material_coding_attribute_value_code', 'category_id',
                 'product_coding_attribute_ids.coding_description', 'product_coding_attribute_ids.input_value')
    def _compute_coding_attribute(self):
        for item in self:
            item.name = ''
            item.name_en = ''
            default_code = item.category_id.code if item.category_id.code else ""
            # 部门参与编码
            if item.is_coding_department:
                department_code = item.department_id.code or 'ZZZ'
                default_code += department_code
            # 供应商参与编码
            if item.is_coding_provider:
                supplier_code = item.coding_provider_id.code or 'ZZZZZ'
                default_code += supplier_code
            # 型号参与编码
            if item.is_model_number:
                model_library_code = item.model_library_id.code or 'ZZ'
                default_code += model_library_code
            for itrm in item.product_coding_attribute_ids:
                # if itrm.sb_material_coding_attribute_id.coding_attribute_type == 'flow_number':
                #     itrm._compute_value_code()
                if itrm.material_coding_attribute_value_code:
                    default_code += itrm.material_coding_attribute_value_code
            item.default_code = default_code
            # 芯板--------------------------------------------------------------------------
            if item.f_category_id and item.f_category_id.code == 'CR':
                # 基材铜厚防呆判断用
                t_code = b_code = ''
                # 尺寸防呆判断用
                sheet_c = pnl_c = False
                # 拼接描述
                str_name_cn = []
                str_name_en = []
                top_name_cn = []
                top_name_en = []
                BLLX = ''
                BLLX_en = ''
                CORET = ''
                CORET_en = ''
                COREV = ''
                COREV_en = ''
                # 属性拼接
                for item2 in item.product_coding_attribute_ids:
                    # 带出物料型号信息
                    if self.model_library_id:
                        if item2.sb_material_coding_attribute_id.code == 'LS' and self.model_library_id.halogen:
                            vid = item2.env['sb.material.coding.attribute.value'].search(
                                [('material_coding_attribute_id', '=', item2.sb_material_coding_attribute_id.id),
                                 ('value_code', '=', self.model_library_id.halogen)], limit=1)
                            o_vid = vid.id != item2.material_coding_attribute_value_id.id if item2.material_coding_attribute_value_id.id else False
                            if vid != o_vid:
                                item2.write({
                                    'material_coding_attribute_value_id': vid.id
                                })
                        if item2.sb_material_coding_attribute_id.code == 'XS' and self.model_library_id.core_color:
                            xvid = item2.env['sb.material.coding.attribute.value'].search(
                                [('material_coding_attribute_id', '=', item2.sb_material_coding_attribute_id.id),
                                 ('value_code', '=', self.model_library_id.core_color)], limit=1)
                            o_xvid = item2.material_coding_attribute_value_id.id if item2.material_coding_attribute_value_id.id else False
                            if xvid and xvid.id != o_xvid:
                                item2.write({
                                    'material_coding_attribute_value_id': xvid.id
                                })
                    # 基材铜厚先小后大判断
                    if item2.sb_material_coding_attribute_id.code == 'JCTHT':
                        t_code = item2.material_coding_attribute_value_code
                    if item2.sb_material_coding_attribute_id.code == 'JCTHB':
                        b_code = item2.material_coding_attribute_value_code
                    if t_code and b_code:
                        custom_array = ['E', 'Q', 'T', 'J', 'H', 'M', '1', 'W',
                                        '2', '3', '4', '5', '6', '7', '8', '9',
                                        'A', 'B', 'C', 'D', 'U', 'F', 'G', 'V', 'K', 'L',
                                        'N', 'P', 'X', 'R', 'S', 'Y']
                        t_index = b_index = False
                        for index, element in enumerate(custom_array):
                            if element == t_code:
                                t_index = index
                            if element == b_code:
                                b_index = index
                        if b_index and t_index and b_index < t_index:
                            raise UserError(_(t_code + 'Greater than' + b_code))

                    # sheet尺寸和pnl尺寸不能同时存在
                    if item2.sb_material_coding_attribute_id.code == 'JCSHEET':
                        sheet_c = item2.material_coding_attribute_value_code
                    if item2.sb_material_coding_attribute_id.code == 'JCPNL':
                        pnl_c = item2.material_coding_attribute_value_code
                    if sheet_c and pnl_c:
                        raise UserError(_('PNL size and Sheet size cannot be entered at the same time'))
                    # 卤素
                    if item2.sb_material_coding_attribute_id.code == "LS" and item2.material_coding_attribute_value_id:
                        top_name_cn.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name or ''))
                        if item2.material_coding_attribute_value_id.name_en and item2.material_coding_attribute_value_id.name_en == 'HF':
                            top_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                    item2.material_coding_attribute_value_id.name_en or '') + '_')
                        else:
                            top_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                    item2.material_coding_attribute_value_id.name_en or ''))
                        # 类别
                        top_name_cn.append(item.category_id.name)
                        top_name_en.append(item.category_id.en_name)
                        # 型号
                        if item.model_library_id and item.model_library_id.name:
                            top_name_cn.append('_' + item.model_library_id.name)
                            top_name_en.append('_' + item.model_library_id.name)
                    item.name = ''.join(top_name_cn)
                    item.name_en = ''.join(top_name_en)
                    # 是否含铜
                    if item2.sb_material_coding_attribute_id.code == "JCTYPE" and item2.material_coding_attribute_value_id:
                        str_name_cn.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name or ''))
                        str_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name_en or ''))
                    # 基材厚度
                    if item2.input_value and item2.sb_material_coding_attribute_id.code == "JCHOU":
                        result = item2.input_value.rstrip('0').rstrip('.')
                        str_name_cn.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                result or ''))
                        str_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                result or ''))
                    # 芯板铜厚
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "JCTHT":
                        str_name_cn.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name or ''))
                        str_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name_en or ''))
                    # 芯板铜厚
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "JCTHB":
                        str_name_cn.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name or ''))
                        str_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name_en or ''))
                    # 芯板结构
                    if item2.input_value and item2.sb_material_coding_attribute_id.code == "XBJG":
                        str_name_cn.append('(' + (
                                item2.input_value or '') + BLLX + CORET + COREV)
                        str_name_en.append('(' + (
                                item2.input_value or '') + BLLX_en + CORET_en + COREV_en)
                    # 铜箔类型
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "BLLX":
                        BLLX = (item2.material_coding_attribute_value_id.name or '') + ')'
                        BLLX_en = (item2.material_coding_attribute_value_id.name_en or '') + ')'
                    # Core厚公差类型
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "CORET":
                        CORET = (item2.material_coding_attribute_value_id.name or '')
                        CORET_en = (item2.material_coding_attribute_value_id.name_en or '')
                    # Core厚公差值
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "COREV":
                        COREV = (item2.material_coding_attribute_value_id.name or '')
                        COREV_en = (item2.material_coding_attribute_value_id.name_en or '')
                    # 芯板sheet尺寸
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "JCSHEET":
                        str_name_cn.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name or ''))
                        str_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name_en or ''))
                    # 芯板pnl尺寸
                    if item2.input_value and item2.sb_material_coding_attribute_id.code == "JCPNL":
                        str_name_cn.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.input_value or ''))
                        str_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.input_value or ''))
                    # 芯色
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "XS":
                        str_name_cn.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name or ''))
                        str_name_en.append((item2.sb_material_coding_attribute_id.description_prefix or '') + (
                                item2.material_coding_attribute_value_id.name_en or ''))
                    # 备用
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "BY":
                        if item2.material_coding_attribute_value_id.name != 'Z':
                            str_name_cn.append(item2.material_coding_attribute_value_id.name or '')
                            str_name_en.append(item2.material_coding_attribute_value_id.name_en or '')
                if str_name_cn:
                    if item.name:
                        item.name = item.name + '' + ''.join(str_name_cn)
                    else:
                        item.name = ''.join(str_name_cn)
                if str_name_en:
                    if item.name_en:
                        item.name_en = item.name_en + '' + ''.join(str_name_en)
                    else:
                        item.name_en = ''.join(str_name_en)
            # PP--------------------------------------------------------------------------
            elif item.f_category_id and item.f_category_id.code == 'BS':
                # 拼接描述
                str_name_cn = []
                str_name_en = []
                top_name_cn = []
                top_name_en = []
                # 属性拼接
                for item2 in item.product_coding_attribute_ids:
                    att_name_cn = att_name_en = ''
                    # 带出物料型号信息
                    if self.model_library_id:
                        if item2.sb_material_coding_attribute_id.code == 'LS' and self.model_library_id.halogen:
                            vid = item2.env['sb.material.coding.attribute.value'].search(
                                [('material_coding_attribute_id', '=', item2.sb_material_coding_attribute_id.id),
                                 ('value_code', '=', self.model_library_id.halogen)], limit=1)
                            if vid:
                                item2.write({
                                    'material_coding_attribute_value_id': vid.id
                                })
                    # 卤素
                    if item2.sb_material_coding_attribute_id.code == "LS" and item2.material_coding_attribute_value_id:
                        top_name_cn.append((item2.material_coding_attribute_value_id.name or ''))
                        if item2.material_coding_attribute_value_id.name_en and item2.material_coding_attribute_value_id.name_en == 'HF':
                            top_name_en.append((
                                        item2.material_coding_attribute_value_id.name_en or '') + '_')
                        else:
                            top_name_en.append((
                                        item2.material_coding_attribute_value_id.name_en or ''))
                        # 类别
                        top_name_cn.append(item.category_id.name)
                        top_name_en.append(item.category_id.en_name)
                        # 型号
                        if item.model_library_id and item.model_library_id.pp_name:
                            top_name_cn.append('_' + item.model_library_id.pp_name)
                            top_name_en.append('_' + item.model_library_id.pp_name)
                        item.name = 'BS_' + ''.join(top_name_cn)
                        item.name_en = 'BS_' + ''.join(top_name_en)
                    if not item2.coding_description:  # 不参与描述直接返回
                        continue
                    if item2.coding_attribute_type == 'input':
                        att_name_cn = (item2.input_value or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                        att_name_en = (item2.input_value or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                    elif item2.sb_material_coding_attribute_id.code != "BY" and item2.sb_material_coding_attribute_id.coding_attribute_type == 'value':
                        att_name_cn = (item2.material_coding_attribute_value_id.name or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                        att_name_en = (item2.material_coding_attribute_value_id.name_en or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                    if att_name_cn:
                        str_name_cn.append(att_name_cn)
                    if att_name_en:
                        str_name_en.append(att_name_en)
                    # 备用
                    if item2.material_coding_attribute_value_id and item2.sb_material_coding_attribute_id.code == "BY":
                        if item2.material_coding_attribute_value_id.name != 'Z':
                            str_name_cn.append((item2.material_coding_attribute_value_id.name or ''))
                            str_name_en.append((item2.material_coding_attribute_value_id.name_en or ''))

                if str_name_cn:
                    if item.name:
                        item.name = item.name + '_' + ''.join(str_name_cn)
                    else:
                        item.name = ''.join(str_name_cn)
                if str_name_en:
                    if item.name_en:
                        item.name_en = item.name_en + '_' + ''.join(str_name_en)
                    else:
                        item.name_en = ''.join(str_name_en)


            # 其它
            else:
                # 分类获取名称
                if item.category_id:
                    item.name = self.get_category_name(item.category_id)
                    item.name_en = self.get_category_name_en(item.category_id)
                str_name_cn = [item.department_id.name + '_'] if item.department_id.name else []  # 中文属性描述
                str_name_en = [item.department_id.name_en + '_'] if item.department_id.name_en else []  # 英文属性描述
                specification = ''
                # 属性拼接
                for item2 in item.product_coding_attribute_ids:
                    if not item2.coding_description:  # 不参与描述直接返回
                        continue
                    if item2.coding_attribute_type == 'desc_input':
                        if not item2.input_value:
                            continue
                        att_name_cn = ''
                        att_name_en = ''
                        lower_name = item2.name.lower()  # 全部转换为小写
                        if 'cn' in lower_name:
                            att_name_cn =(item2.input_value or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                        if 'en' in lower_name:
                            att_name_en = (item2.input_value or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                        if 'cn' not in lower_name and 'en' not in lower_name:
                            specification = (item2.input_value or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                            str_name_cn.append(specification)
                            str_name_en.append(specification)
                    elif item2.coding_attribute_type == 'input':
                        att_name_cn = (item2.input_value or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                        att_name_en = (item2.input_value or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                    else:
                        att_name_cn = (item2.material_coding_attribute_value_id.name or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                        att_name_en = (item2.material_coding_attribute_value_id.name_en or '') + (item2.sb_material_coding_attribute_id.description_prefix or '')
                    if att_name_cn:
                        str_name_cn.append(att_name_cn)
                    if att_name_en:
                        str_name_en.append(att_name_en)
                if str_name_cn:
                    if item.name:
                        item.name = item.name + '_' + ''.join(str_name_cn)
                    else:
                        item.name = ''.join(str_name_cn)
                if str_name_en:
                    if item.name_en:
                        item.name_en = item.name_en + '_' + ''.join(str_name_en)
                    else:
                        item.name_en = ''.join(str_name_en)
                item.specification = specification

    def button_done(self):
        """
        生成产品
        """
        self.ensure_one()
        if self.product_tmpl_id:
            raise UserError(_('The product has been generated, please do not repeat the operation'))
        model = self.env['product.template'].sudo()
        if not self.default_code:
            raise UserError(_('The product code cannot be empty'))
        att_ids = []
        spec = ''
        standards = ''
        for item in self.product_coding_attribute_ids:
            # 流水号自动迭代
            if item.sb_material_coding_attribute_id.coding_attribute_type == 'flow_number':
                # cag = self.search([('category_id', '=', self.category_id.id),
                #                    ('state', '=', 'done'),
                #                    ('id', '!=', self.id)])
                # num = len(cag) + 1
                num = self.category_id.flow_number + 1
                self.category_id.sudo().write({'flow_number': num})
                co = f"{num:0{item.input_length}}"
                item.write({'material_coding_attribute_value_code': co})
            if item.sb_material_coding_attribute_id.code == 'SPEC':
                spec = item.input_value
            if not spec and self.model_library_id:
                spec = self.model_library_id.name

            elif item.sb_material_coding_attribute_id.code == 'STAN':
                standards = item.input_value

            att_ids.append((0, 0, {
                'sb_material_coding_attribute_id': item.sb_material_coding_attribute_id.id,
                'material_coding_attribute_value_id': item.material_coding_attribute_value_id.id,
                'material_coding_attribute_value_code': item.material_coding_attribute_value_code,
                'coding_attribute_type': item.coding_attribute_type,
                'coding_description': item.coding_description,
                'coding_participation': item.coding_participation,
                'department_id': item.department_id.id,
                'coding_provider_id': item.coding_provider_id.id,
                'input_length': item.input_length,
                'input_value': item.input_value,
                'sequence': item.sequence,
                'core_board_sum': item.core_board_sum,
            }))
        self.state = 'done'
        self._compute_coding_attribute()
        # 准备数据
        vals = {
            'name': self.name,
            'default_code': self.default_code,
            'categ_id': self.category_id.id,
            'coding_provider_id': self.coding_provider_id.id,
            'description_eng': self.name_en,
            'specification_eng': spec,  # 型号英
            'standards': standards,
            'versions': 'A0',
            'sale_ok': False,
            'purchase_ok': True,
            'type': 'product',
            'tracking': 'lot',
            'uom_id': self.uom_id.id,
            'uom_po_id': self.uom_po_id.id,
            'product_template_coding_attribute_ids': att_ids,
        }
        product = model.create(vals)
        self.write({
            'product_tmpl_id': product.id
        })

    def action_view_product_tmpl(self):
        form_id = self.env.ref('product.product_template_only_form_view').id
        return {
            'name': 'Product Template',
            'type': 'ir.actions.act_window',
            'res_model': 'product.template',
            'view_mode': 'form',
            'target': 'current',
            'res_id': self.product_tmpl_id.id,
            'views': [[form_id, 'form']],
        }

    @api.model_create_multi
    def create(self, vals_list):
        res = super(ProductCodingTemplate, self).create(vals_list)
        for re in res:
            # 当查询不到ids复制时， 重置一遍类别选择
            if not re.product_coding_attribute_ids and re.category_id:
                cat_id = re.category_id.id
                re.write({
                    'category_id': False
                })
                re.onchange_categ_id()
                re.write({
                    'category_id': cat_id
                })
                re.onchange_categ_id()
        return res

    def unlink(self):
        for item in self:
            if item.product_tmpl_id and item.product_tmpl_id.active:
                raise ValidationError(_('The product has been generated, please do not delete'))
        return super(ProductCodingTemplate, self).unlink()

    @api.onchange('uom_id')
    def _compute_uom_po_id(self):
        if self.uom_id:
            self.uom_po_id = self.uom_id.id
        # else:
        #     self.uom_po_id = 1
